home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Resources / Chat & Communication / Digsby build 37 / digsby_setup.exe / lib / mail / smtp.pyo (.txt) < prev    next >
Python Compiled Bytecode  |  2008-10-13  |  12KB  |  370 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.5)
  3.  
  4. import traceback
  5. from common import profile
  6. from util import unpack_pstr, pack_pstr
  7. from common.emailaccount import EmailAccount
  8. from AccountManager import NETWORK_FLAG
  9. from prefs import localprefprop
  10. SMTP_UPGRADING = True
  11. import smtplib
  12. import re
  13. MAXHEADERLEN = 76
  14.  
  15. class SMTPsender:
  16.     _ignore_domains = []
  17.     addrfmt = '[\\w\\d_\\.\\-\\+=]+\\@(?:(?:[\\w\\d\\-])+\\.)+(?:[\\w\\d]{2,4})'
  18.     shortaddr_re = re.compile('%s$' % addrfmt)
  19.     longaddr_re = re.compile('^\\s*(.*)\\s+<(%s)>\\s*$' % addrfmt)
  20.     
  21.     def __init__(self, name, password, server, port = 25, use_tls = False, from_name = None, reply_to = None):
  22.         self.user_name = name
  23.         self.password = password
  24.         self.smtp_server = server
  25.         self.smtp_port = port
  26.         self.from_name = None if from_name is not None else name
  27.         self.replyto_email = None if reply_to is not None else name
  28.         self._use_tls = use_tls
  29.         self._init_pref_encoding()
  30.  
  31.     
  32.     def format_header(self, key, name, email = None):
  33.         Header = Header
  34.         import email.Header
  35.         maxlength = MAXHEADERLEN - len(key) + 2
  36.         if maxlength < 10:
  37.             raise AssertionError, 'Header length is too short'
  38.         
  39.         
  40.         try:
  41.             tmp = None if isinstance(name, unicode) else name
  42.             header = Header(tmp, 'utf-8', maxlinelen = maxlength)
  43.         except UnicodeEncodeError:
  44.             header = Header(name, self._charset, maxlinelen = maxlength)
  45.  
  46.         if not email:
  47.             return header
  48.         else:
  49.             return '"%s" <%s>' % (header, email)
  50.  
  51.     
  52.     def add_headers(self, msg, headers):
  53.         for h in headers:
  54.             msg[h] = self.encode_header(h, headers[h])
  55.         
  56.  
  57.     
  58.     def get_smtp_address(self, address):
  59.         if not address:
  60.             return None
  61.         
  62.         
  63.         def is_email(address):
  64.             pos = address.find('@')
  65.             if pos == -1:
  66.                 return False
  67.             
  68.             if address[pos + 1:].lower() in self._ignore_domains:
  69.                 return False
  70.             
  71.             return True
  72.  
  73.         if not is_email(address):
  74.             if address == 'anonymous':
  75.                 return None
  76.             
  77.             if self.email_map.has_key(address):
  78.                 address = self.email_map[address]
  79.             elif SMTPsender.nodomaddr_re.match(address):
  80.                 if self.config.getbool('notification', 'use_short_addr'):
  81.                     return address
  82.                 
  83.                 domain = self.config.get('notification', 'smtp_default_domain')
  84.                 if domain:
  85.                     address = '%s@%s' % (address, domain)
  86.                 else:
  87.                     self.env.log.info('Email address w/o domain: %s' % address)
  88.                     return None
  89.             
  90.         
  91.         mo = self.shortaddr_re.search(address)
  92.         if mo:
  93.             return mo.group(0)
  94.         
  95.         mo = self.longaddr_re.search(address)
  96.         if mo:
  97.             return mo.group(2)
  98.         
  99.         self.env.log.info('Invalid email address: %s' % address)
  100.  
  101.     
  102.     def _init_pref_encoding(self):
  103.         Charset = Charset
  104.         QP = QP
  105.         BASE64 = BASE64
  106.         import email.Charset
  107.         self._charset = Charset()
  108.         self._charset.input_charset = 'utf-8'
  109.         pref = 'base64'
  110.         if pref == 'base64':
  111.             self._charset.header_encoding = BASE64
  112.             self._charset.body_encoding = BASE64
  113.             self._charset.output_charset = 'utf-8'
  114.             self._charset.input_codec = 'utf-8'
  115.             self._charset.output_codec = 'utf-8'
  116.         elif pref in ('qp', 'quoted-printable'):
  117.             self._charset.header_encoding = QP
  118.             self._charset.body_encoding = QP
  119.             self._charset.output_charset = 'utf-8'
  120.             self._charset.input_codec = 'utf-8'
  121.             self._charset.output_codec = 'utf-8'
  122.         elif pref == 'none':
  123.             self._charset.header_encoding = None
  124.             self._charset.body_encoding = None
  125.             self._charset.input_codec = None
  126.             self._charset.output_charset = 'ascii'
  127.         else:
  128.             raise AssertionError, 'Invalid email encoding setting: %s' % pref
  129.  
  130.     
  131.     def encode_header(self, key, value):
  132.         if isinstance(value, tuple):
  133.             return self.format_header(key, value[0], value[1])
  134.         
  135.         if isinstance(value, list):
  136.             items = []
  137.             for v in value:
  138.                 items.append(self.encode_header(v))
  139.             
  140.             return ',\n\t'.join(items)
  141.         
  142.         mo = self.longaddr_re.match(value)
  143.         if mo:
  144.             return self.format_header(key, mo.group(1), mo.group(2))
  145.         
  146.         return self.format_header(key, value)
  147.  
  148.     
  149.     def begin_send(self):
  150.         self.server = smtplib.SMTP(self.smtp_server, self.smtp_port)
  151.         if self._use_tls:
  152.             self.server.ehlo()
  153.             if not self.server.esmtp_features.has_key('starttls'):
  154.                 raise AssertionError, 'TLS enabled but server does not support TLS'
  155.             
  156.             self.server.starttls()
  157.             self.server.ehlo()
  158.         
  159.         if self.user_name:
  160.             
  161.             try:
  162.                 self.server.login(self.user_name, self.password)
  163.  
  164.         
  165.  
  166.     
  167.     def send_email(self, to = '', subject = '', body = '', cc = '', bcc = ''):
  168.         self.begin_send()
  169.         self.send([
  170.             to], [], subject, body)
  171.         
  172.         try:
  173.             self.finish_send()
  174.         except:
  175.             pass
  176.  
  177.  
  178.     
  179.     def send(self, torcpts, ccrcpts, subject, body, mime_headers = { }):
  180.         MIMEText = MIMEText
  181.         import email.MIMEText
  182.         headers = { }
  183.         headers['Subject'] = subject
  184.         headers['From'] = (self.from_name, self.from_name)
  185.         
  186.         def build_addresses(rcpts):
  187.             return []([], [ self.get_smtp_address(addr) for addr in rcpts ])
  188.  
  189.         
  190.         def remove_dup(rcpts, all):
  191.             tmp = []
  192.             for rcpt in rcpts:
  193.                 if rcpt not in all:
  194.                     tmp.append(rcpt)
  195.                     all.append(rcpt)
  196.                     continue
  197.             
  198.             return (tmp, all)
  199.  
  200.         toaddrs = build_addresses(torcpts)
  201.         recipients = []
  202.         (toaddrs, recipients) = remove_dup(toaddrs, recipients)
  203.         if len(recipients) < 1:
  204.             return None
  205.         
  206.         headers['To'] = ', '.join(toaddrs)
  207.         msg = MIMEText(body.encode('utf-8'), 'plain')
  208.         del msg['Content-Transfer-Encoding']
  209.         msg.set_charset(self._charset)
  210.         self.add_headers(msg, headers)
  211.         self.add_headers(msg, mime_headers)
  212.         msgtext = msg.as_string()
  213.         recrlf = re.compile('\r?\n')
  214.         msgtext = '\r\n'.join(recrlf.split(msgtext))
  215.         self.server.sendmail(msg['From'], recipients, msgtext)
  216.  
  217.     
  218.     def finish_send(self):
  219.         if self._use_tls:
  220.             import socket as socket
  221.             
  222.             try:
  223.                 self.server.quit()
  224.             except socket.sslerror:
  225.                 pass
  226.             except:
  227.                 None<EXCEPTION MATCH>socket.sslerror
  228.             
  229.  
  230.         None<EXCEPTION MATCH>socket.sslerror
  231.         self.server.quit()
  232.  
  233.  
  234. from common.emailaccount import EmailAccount
  235. from util import threaded
  236.  
  237. class SMTPEmailAccount(EmailAccount):
  238.     DEFAULT_SMTP_REQUIRE_SSL = False
  239.     DEFAULT_SMTP_PORT = 25
  240.     
  241.     def __init__(self, **options):
  242.         d = self.default
  243.         self.smtp_server = options.pop('smtp_server', d('smtp_server'))
  244.         self.smtp_require_ssl = options.pop('smtp_require_ssl', d('smtp_require_ssl'))
  245.         self.smtp_port = options.pop('smtp_port', d('smtp_port'))
  246.         self.smtp_username = options.pop('smtp_username', d('smtp_username'))
  247.         self._email_address = options.pop('email_address', d('email_address'))
  248.         self._encrypted_smtppw = profile.crypt_pw(options.pop('smtp_password', d('smtp_password')))
  249.         self._encrypted_pw = options.pop('password')
  250.         EmailAccount.__init__(self, password = self.password, **options)
  251.  
  252.     
  253.     def get_email_address(self):
  254.         return self._email_address
  255.  
  256.     
  257.     def set_email_address(self, val):
  258.         self._email_address = val
  259.  
  260.     
  261.     def from_name(self):
  262.         return self.email_address
  263.  
  264.     from_name = property(from_name)
  265.     
  266.     def _unglue_pw(cls, password):
  267.         passwordstr = profile.plain_pw(password).encode('utf-8')
  268.         (password, r) = unpack_pstr(passwordstr)
  269.         
  270.         try:
  271.             (smtppassword, r) = unpack_pstr(r)
  272.         except:
  273.             (smtppassword, r) = (u'', u'')
  274.  
  275.         return (profile.crypt_pw(password.decode('utf-8')), profile.crypt_pw(smtppassword.decode('utf-8')))
  276.  
  277.     _unglue_pw = classmethod(_unglue_pw)
  278.     
  279.     def _set_password(self, password):
  280.         
  281.         try:
  282.             (self._encrypted_pw, self._encrypted_smtppw) = self._unglue_pw(password)
  283.         except Exception:
  284.             e = None
  285.             traceback.print_exc()
  286.             self._encrypted_pw = password
  287.             self._encrypted_smtppw = ''
  288.  
  289.  
  290.     
  291.     def _glue_pw(cls, encrypted_pw, encrypted_smtppw):
  292.         password = pack_pstr(profile.plain_pw(encrypted_pw).encode('utf-8')).decode('utf-8')
  293.         smtppw = pack_pstr(profile.plain_pw(encrypted_smtppw).encode('utf-8')).decode('utf-8')
  294.         return profile.crypt_pw(password + smtppw)
  295.  
  296.     _glue_pw = classmethod(_glue_pw)
  297.     
  298.     def _get_password(self):
  299.         return self._glue_pw(self._encrypted_pw, self._encrypted_smtppw)
  300.  
  301.     password = property(_get_password, _set_password)
  302.     
  303.     def _decryptedpw(self):
  304.         return profile.plain_pw(self._encrypted_pw)
  305.  
  306.     
  307.     def _decrypted_smtppw(self):
  308.         return profile.plain_pw(self._encrypted_smtppw)
  309.  
  310.     smtp_password = property(_decrypted_smtppw)
  311.     
  312.     def update_info(self, **info):
  313.         if not self.isflagged(NETWORK_FLAG):
  314.             if 'password' in info:
  315.                 self._encrypted_pw = info.pop('password')
  316.             
  317.             if 'smtp_password' in info:
  318.                 self._encrypted_smtppw = profile.crypt_pw(info.pop('smtp_password'))
  319.             
  320.         else:
  321.             self.password = info.pop('password')
  322.         EmailAccount.update_info(self, **info)
  323.  
  324.     
  325.     def _get_options(self):
  326.         opts = EmailAccount._get_options(self)
  327.         opts.update((dict,)((lambda .0: for a in .0:
  328. (a, getattr(self, a)))('smtp_server smtp_port smtp_require_ssl smtp_username email_address'.split())))
  329.         return opts
  330.  
  331.     
  332.     def from_net(cls, info):
  333.         password = info.password
  334.         
  335.         try:
  336.             (encrypted_pw, encrypted_smtppw) = cls._unglue_pw(password)
  337.         except Exception:
  338.             e = None
  339.             traceback.print_exc()
  340.             encrypted_pw = password
  341.             encrypted_smtppw = u''
  342.  
  343.         info.password = encrypted_pw
  344.         smtppw = profile.plain_pw(encrypted_smtppw)
  345.         return EmailAccount.from_net(info, smtp_password = smtppw)
  346.  
  347.     from_net = classmethod(from_net)
  348.     
  349.     def send_email(self, to = '', subject = '', body = '', cc = '', bcc = ''):
  350.         if not self.smtp_username:
  351.             pass
  352.         un = self.username
  353.         f = self.from_name
  354.         if not self._decrypted_smtppw():
  355.             pass
  356.         password = None if not self.smtp_username else ''
  357.         srv = self.smtp_server
  358.         if srv in ('smtp.aol.com', 'smtp.aim.com'):
  359.             if un.endswith('aol.com') or un.endswith('aim.com'):
  360.                 f = un
  361.             else:
  362.                 f = un + u'@aol.com'
  363.         
  364.         s = SMTPsender(un, password, srv, from_name = f, use_tls = self.smtp_require_ssl)
  365.         s.send_email(to = to, subject = subject, body = body, cc = cc, bcc = bcc)
  366.  
  367.     send_email = threaded(send_email)
  368.     mailclient = localprefprop(EmailAccount.mailclient_localprefs_key, 'sysdefault')
  369.  
  370.